package cn.xianshu.user.service.impl;

import cn.xianshu.basic.service.impl.BasicServiceImpl;
import cn.xianshu.basic.util.MD5Utils;
import cn.xianshu.basic.util.PageList;
import cn.xianshu.basic.util.StrUtils;
import cn.xianshu.basic.util.UserContants;
import cn.xianshu.user.domain.Logininfo;
import cn.xianshu.user.domain.User;
import cn.xianshu.user.dto.UserDto;
import cn.xianshu.user.mapper.LogininfoMapper;
import cn.xianshu.user.mapper.UserMapper;
import cn.xianshu.user.query.UserQuery;
import cn.xianshu.user.service.IUserService;
import org.apache.ibatis.builder.BuilderException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;


@Service
public class UserServiceImpl extends BasicServiceImpl<User> implements IUserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private LogininfoMapper logininfoMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public PageList<User> pageQuery(UserQuery query) {
        // 总条数
        Integer total = userMapper.count(query);
        // 每页显示数据
        List<User> rows = userMapper.queryData(query);
        return new PageList<>(total, rows);
    }

    /**
     * 手机注册
     * @param userDto
     */
    @Override
    @Transactional
    public void phoneRegister(UserDto userDto) {
        // 校验
        //  1.非空校验 四个
        if (StringUtils.isEmpty(userDto.getPhone())
            || StringUtils.isEmpty(userDto.getVerifyCode())
            || StringUtils.isEmpty(userDto.getPassword())
            || StringUtils.isEmpty(userDto.getPasswordRepeat())){

            throw new BuilderException("请输入相关信息再注册！");
        }
        // 2.手机号是否被注册
        User userTmp = userMapper.loadByPhone(userDto.getPhone());
        if (userTmp != null){
            throw new BuilderException("用户已注册，请直接登录");
        }
        // 3.两次密码是否一致
        if (!userDto.getPassword().equals(userDto.getPasswordRepeat())){
            throw new BuilderException("两次密码不一致");
        }
        // 4.验证码校验
        Object codeObj = redisTemplate.opsForValue().get(UserContants.REGISTER_CODE_PREFIX + userDto.getPhone());
        if (codeObj == null){
            throw new BuilderException("验证码已失效，请重新获取手机验证码！");
        } else {
            // 从Redis获取的验证码和用户输入的验证码进行对比
            String redisCode = codeObj.toString().split(":")[0];
            if (!redisCode.equalsIgnoreCase(userDto.getVerifyCode())){
                throw new BuilderException("验证码不正确，请重新输入!");
            }
        }
        // 将数据保存到数据库  user， logininfo
        // 先保存 logininfo
        // 准备user数据和logininfo数据
        User user = userDto2User(userDto);
        Logininfo logininfo = user2Logininfo(user);
        logininfoMapper.insert(logininfo);

        user.setLogininfo_id(logininfo.getId());
        userMapper.insert(user);
    }

    private Logininfo user2Logininfo(User user){
        Logininfo logininfo = new Logininfo();
        // copy user 中的数据到logininfo中
        BeanUtils.copyProperties(user, logininfo);
        logininfo.setType(1);
        logininfo.setDisable(1);
        return logininfo;
    }

    public User userDto2User(UserDto userDto){
        User user = new User();
        user.setUsername(userDto.getPhone());
        user.setPhone(userDto.getPhone());
        user.setState(1);

        // 盐值
        String salt = StrUtils.getComplexRandomString(32);
        // 密码: 加密加盐
        String password = MD5Utils.encrypByMd5(salt + userDto.getPassword());


        user.setSalt(salt);
        user.setPassword(password);
        return user;
    }

}
